package de.rs.espresso.algorithms.model;

import java.util.ArrayList;
import java.util.HashSet;

import de.rs.espresso.interfaces.ICube;
import de.rs.espresso.interfaces.ICover;

public class FreeSet {

	HashSet<Integer> values = new HashSet<Integer>();

	private ICube cube;

	public FreeSet(ICube cube) {

		this.cube = cube;

		int numberOfBits = cube.getNumberOfLiterals() * 2;

		for (int position = 0; position < numberOfBits; position++) {
			if (!cube.isPartSet(position))
				values.add(position);

		}
	}

	public void removeEssentials(ICover offSet) {
		HashSet<Integer> toRemove = new HashSet<Integer>();
		for (int value : values) {
			//Never raised:
			int literal = value/2;
			if (offSet.neverRaisedAt(cube, literal)) {
				toRemove.add(value);
			} else 
			//Always raised:	
			if (offSet.isPartNeverSet(value)) {
				cube.raisePart(value);
				toRemove.add(value);

			}
		}
		values.removeAll(toRemove);
	}
	
	public void changeCube(ICube cube) {
		this.cube = cube;
	}
	
	public boolean isEmpty() {
		return values.isEmpty();
	}

	/**
	 * Deletes the entries of FreeSet, which are set in the given ICube.
	 * @param beta
	 */
	public void removeSetPartsOf(ICube beta) {
		ArrayList<Integer> toRemove = new ArrayList<Integer>();
		for(int value : values)
			if(beta.isPartSet(value))
				toRemove.add(value);
		values.removeAll(toRemove);
	}

	public ICube getOverexpandedCube() {
		ICube clonedCube = cube.clone();
		for(int value : values)
			clonedCube.raisePart(value);
		return clonedCube;
	}

	public int popMostOccuringPart(ICover coveredCubes) {
		int maxOccuring = 0;
		int maxOccuringValue = -1;
		for(int value : values) {
			int occuring = coveredCubes.countOccuringOfPart(value);
			if(occuring>=maxOccuring) {
				maxOccuring = occuring;
				maxOccuringValue = value;
			}
		}
		
		values.remove(maxOccuringValue);
		
		return maxOccuringValue;

		
	}
	
	public String toString() {
		return cube+" | "+values;
	}

}
